﻿#if !UNITY_IOS || HUpdate
using System;
using System.Collections.Generic;
using System.IO;

namespace UnityModule
{
    public partial class DownloadComponent
    {
        /// <summary>
        /// 所有下载任务
        /// </summary>
        private readonly Dictionary<string, DownloadTask> m_DicDownloading = new Dictionary<string, DownloadTask>();
        DLoadZipTask m_DLoadZipTask;

        /// <summary>
        /// 等待队列
        /// </summary>
        private readonly Queue<DownloadTask> m_HightQueue = new Queue<DownloadTask>();

        /// <summary>
        /// 等待队列
        /// </summary>
        private readonly Queue<DownloadTask> m_LowQueue = new Queue<DownloadTask>();

        DownloadWatcher dlWatcher = new DownloadWatcher();

        public int m_failCount = 0;
        public bool m_beforeFinish = false;//提前结束
        public string m_dloadUrl;
        public string m_zipName;

        private void DLoadZip(string url ,string zipName)
        {
            m_DLoadZipTask = new DLoadZipTask(url, zipName);
            m_DLoadZipTask.Callback += DLoadZipComplete;
            m_DLoadZipTask.Progress += DLoadZipProgress;
            m_DLoadZipTask.ResumeBreakpoint = true;
            m_DLoadZipTask.Download();
        }
        /// <summary>
        /// 开始一个下载
        /// </summary>
        /// <param name="abName"></param>
        /// <param name="callback"></param>
        /// <param name="progress"></param>
        /// <param name="isHidePriority">优先下载</param>
        private void AddDownloadTask(AssetBundleInfoV2 bundleInfo, Action<string, string> callback, Action<long, long> progress, bool isHidePriority)
        {
            DownloadTask downloadTask = null;

            bool isCreateTask = !m_DicDownloading.TryGetValue(bundleInfo.abNameWithHash, out downloadTask);
            if (isCreateTask)
            {
                //新建下载任务
                downloadTask = new DownloadTask(UpdateSettings.Instance.CdnUrl, bundleInfo);
                downloadTask.Mode = DownloadClientConfig.DefaultDownloadType;
                m_DicDownloading.Add(bundleInfo.abNameWithHash, downloadTask);
                downloadTask.ResumeBreakpoint = DownloadClientConfig.HTTP_RESUME;
                //设置默认回调
                downloadTask.Callback += OnDownloadTaskDone;
            }
            downloadTask.ResumeBreakpoint = DownloadClientConfig.HTTP_RESUME || bundleInfo.breakpoint == 1;
            //设置下载完成回调
            downloadTask.Callback += callback;
            //设置下载进度回调
            downloadTask.Progress += progress;
            downloadTask.OnError += DownloadTask_OnError;
            //优先级提升
            bool isUpgrade = false;
            if (isHidePriority)
            {
                isUpgrade = downloadTask.UpgradePriority();
            }

            if (downloadTask.State == DownloadTask.TaskState.Waiting)
            {
                //创建或优先级提升时, 不必从原队列中移除, 从队列中获取任务时再判断
                if (isCreateTask || isUpgrade)
                {
                    if (downloadTask.IsHidePriority)
                    {
                        m_HightQueue.Enqueue(downloadTask);
                    }
                    else
                    {
                        m_LowQueue.Enqueue(downloadTask);
                    }
                }
            }
        }

        private void DownloadTask_OnError(DownloadTask.emError obj)
        {
            if (obj == DownloadTask.emError.DiskFull) {
                //UpdateStepUtility.StorgeFullError();
            }
        }

        bool DownloadPause = false;
        void CheckQueueDownload()
        {
            if (DownloadPause)
                return;
            
            if (m_HightQueue.Count > 0)
            {
                if (DownloadTask.RunningTaskNum <  DownloadClientConfig.HighTaskMaxRunningCount+ DownloadClientConfig.LowTaskMaxRunningCount)
                {
                    DownloadTask task = m_HightQueue.Dequeue();
                    if (task.State == DownloadTask.TaskState.Waiting)
                        task.Download();
                    return;

                }
            }
            if (m_LowQueue.Count > 0)
            {
                if (DownloadTask.RunningTaskNum < DownloadClientConfig.LowTaskMaxRunningCount)
                {
                    DownloadTask task = m_LowQueue.Dequeue();
                    if (task.State == DownloadTask.TaskState.Waiting)
                        task.Download();
                    return;
                }
            }
        }
      
        Action allDownloadTaskFinished;
        //加载任务回调
        private void OnDownloadTaskDone(string retAbName, string exception)
        {
            m_DicDownloading.Remove(retAbName);
            if (DownloadTask.RunningTaskNum == 0 && DownloadPause) {
                allDownloadTaskFinished?.Invoke();
            }
            //ContinueDownload(retAbName, exception);
        }


        //继续下载
        //private void ContinueDownload(string retAbName, string exception)
        //{
        //    if (DownloadPause)
        //        return;

        //    DownloadTask temp = null;

        //    while (DownloadTask.RunningTaskNum <= DownloadClientConfig.HighTaskMaxRunningCount && m_HightQueue.Count > 0)
        //    {
        //        temp = m_HightQueue.Dequeue();

        //        if (temp.State == DownloadTask.TaskState.Waiting)
        //        {
        //            temp.Download();
        //        }
        //    }

        //    while (DownloadTask.RunningTaskNum <= DownloadClientConfig.LowTaskMaxRunningCount && m_LowQueue.Count > 0)
        //    {
        //        temp = m_LowQueue.Dequeue();

        //        if (temp.State == DownloadTask.TaskState.Waiting)
        //        {
        //            temp.Download();
        //        }
        //    }
        //}

        //Test: 删除所有缓存文件
        private void DeleteAllCacheFile()
        {
            string savePath = ApplicationPath.ABCachePath;
            if (Directory.Exists(savePath))
            {
                Directory.Delete(savePath, true);
            }
        }


        public void Pause() {
            DownloadPause = true;
        }
        public void Resume() {
            DownloadPause = false;
        }

        public DownloadTask GetDownloadTask(string AbWhitOutHash) {
            DownloadTask downloadTask = null;
            if (VersionComponent.Instance.CdnBundleInfos.TryGetValue(AbWhitOutHash, out AssetBundleInfoV2 info)) {
                m_DicDownloading.TryGetValue(info.abNameWithHash, out downloadTask);
            }
            return downloadTask;
        }
    }
}
#endif